#include <netinet/in.h>    // for sockaddr_in
#include <sys/types.h>    // for socket
#include <sys/socket.h>    // for socket
#include <stdio.h>        // for printf
#include <stdlib.h>        // for exit
#include <string.h>        // for bzero
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

#define SERVER_PORT  9092
#define LENGTH_OF_LISTEN_QUEUE 2
#define BUFFER_SIZE 256

int main(int argc, char **argv)
{
    struct sockaddr_in server_addr;
    bzero(&server_addr,sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    server_addr.sin_addr.s_addr = htons(INADDR_ANY);
    server_addr.sin_port = htons(SERVER_PORT);

    int server_socket = socket(PF_INET,SOCK_STREAM,0);
    if( server_socket < 0)
    {
        printf("Create Socket Failed!");
        exit(1);
    }
	int opt =1;
	setsockopt(server_socket,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt));
    
    if( bind(server_socket,(struct sockaddr*)&server_addr,sizeof(server_addr)))
    {
        printf("Server Bind Port : %d Failed!", SERVER_PORT); 
        exit(1);
    }

    if ( listen(server_socket, LENGTH_OF_LISTEN_QUEUE) )
    {
        printf("Server Listen Failed!"); 
        exit(1);
    }

	printf("[SERVER]\n"); 
	printf("[PORT]: %d\n", SERVER_PORT); 
	printf("\n"); 
    while (1)
    {
        struct sockaddr_in client_addr;
        socklen_t length = sizeof(client_addr);
        int new_server_socket = accept(server_socket,(struct sockaddr*)&client_addr,&length);
        if ( new_server_socket < 0)
        {
            printf("Server Accept Failed!\n");
            break;
        }
        
        char buffer[BUFFER_SIZE];
		while(1) {
			bzero(buffer, BUFFER_SIZE);
			length = recv(new_server_socket,buffer,BUFFER_SIZE,0);
			//if (length == BUFFER_SIZE)
			if (length > 0)
			{
				printf("[MSG]:"); 
				int i;
				for (i = 0; i < BUFFER_SIZE; ++i) {
					//printf("%02x", buffer[i]); 
					printf("%c", buffer[i]); 
				}
				printf("\n"); 
			}
		}
        close(new_server_socket);
    }
    close(server_socket);
    return 0;
}

